package com.ctrlspace.core.compiler;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Compiler {

	public boolean compile(String projectPath) throws IOException{
		File[] listOfDirectories = new File(projectPath).listFiles();
		String srcDirectoryPath="";
		String webInfDirectoryPath="";
		for(int i=0; i<listOfDirectories.length; i++){
			if(listOfDirectories[i].isDirectory() && listOfDirectories[i].getName().equals("src")){
				srcDirectoryPath = listOfDirectories[i].getPath();
			}else if(listOfDirectories[i].isDirectory() && listOfDirectories[i].getName().equals("war")){
				webInfDirectoryPath = listOfDirectories[i].getPath();
			}
		}
		
		ArrayList<String> srcFiles = getSrcFiles(srcDirectoryPath);
		ArrayList<String> libFiles = getLibraries(webInfDirectoryPath);
		String temp="";
		for(int i=1; i<libFiles.size(); i++){
			temp += libFiles.get(i);
			temp += ";";
		}
		
		String classesPath = getClassFolderPath(webInfDirectoryPath);
		List<String> options = Arrays.asList("-classpath", temp, "-d", classesPath);
		
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
	    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
	    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
	    Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromStrings(srcFiles);
	    JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits);
	    boolean success = task.call();
	    fileManager.close();
	    
	    return success;
	}
	
	private ArrayList<String> getSrcFiles(String directory){
		ArrayList<String> listOfSrcFiles = new ArrayList<String>();
		File[] directories = new File(directory).listFiles();
		
		for(int i=0; i<directories.length; i++){
			if(directories[i].isDirectory() && !directories[i].getName().equals("META-INF")){
				ArrayList<String> tempList = getSrcFiles(directories[i].getPath());
				for(String s: tempList){
					listOfSrcFiles.add(s);
				}
			}else if(directories[i].isFile() && directories[i].getName().endsWith(".java")){
				listOfSrcFiles.add(directories[i].getPath());
			}
		}
		
		return listOfSrcFiles;
	}
	
	private ArrayList<String> getLibraries(String directory){
		ArrayList<String> listOfLibraries = new ArrayList<String>();
		listOfLibraries.add("-classpath");

		String webInfPath="";
		File[] warDirectories = new File(directory).listFiles();
		for(int i=0; i<warDirectories.length; i++){
			if(warDirectories[i].getName().equals("WEB-INF")){
				webInfPath = warDirectories[i].getPath();
				break;
			}
		}
		
		String libPath="";
		File[] webInfDirectories = new File(webInfPath).listFiles();
		for(int i=0; i<webInfDirectories.length; i++){
			if(webInfDirectories[i].getName().equals("lib")){
				libPath = webInfDirectories[i].getPath();
				break;
			}
		}
		
		File[] libContents = new File(libPath).listFiles();
		for(File f: libContents){
			listOfLibraries.add(f.getPath());
		}
		
		return listOfLibraries;
	}
	
	private String getClassFolderPath(String directory){
		String webInfPath="";
		File[] warDirectories = new File(directory).listFiles();
		for(int i=0; i<warDirectories.length; i++){
			if(warDirectories[i].getName().equals("WEB-INF")){
				webInfPath = warDirectories[i].getPath();
				break;
			}
		}
		
		String classesPath="";
		File[] webInfDirectories = new File(webInfPath).listFiles();
		for(int i=0; i<webInfDirectories.length; i++){
			if(webInfDirectories[i].getName().equals("classes")){
				classesPath = webInfDirectories[i].getPath();
				break;
			}
		}
		
		return classesPath;
	}
	
	private String[] convert(List<String> listOfPaths){
		String[] list = new String[listOfPaths.size()];
		
		for(int i=0; i<listOfPaths.size(); i++){
			list[i] = listOfPaths.get(i);
		}
		
		return list;
 	}
}
